package com.adtech.adms.system.datadictionary;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.xml.Unmarshaller;
import org.xml.sax.InputSource;

import com.adtech.adms.Constants;
import com.adtech.adms.commons.util.BeanUtilsEx;
import com.adtech.core.util.FileUtil;
import com.adtech.core.util.ReflectUtil;

/**
 * 数据字典辅助类
 * 加载数据字典配置，提供统一访问接口
 * @author Dormin 
 * @since 2011-6-14 
 * 
 * @Copyright (C) AD Tech Workshop All Right Reserved
 */
public class DataDictionaryHelper {
	private static Logger log = Logger.getLogger(DataDictionaryHelper.class);
	private static DataTypeList dataTypeList;
	private static Map<Integer,DataType> dataTypeMap = new HashMap<Integer,DataType>();

	/**
	 * 
	 * @function 返回数据类型列表
	 * @param
	 *
	 * @return DataTypeList 数据字典类型列表
	 * @exception
	 *
	 * @author Dormin
	 * @history
	 *
	 */
	public static DataTypeList getDataTypeList() {
		if (dataTypeList == null) {
			init();
		}
		
		return dataTypeList;
	}

	/**
	 * 
	 * @function 加载数据字典信息
	 *
	 * @return
	 * @exception
	 *
	 * @author Dormin
	 * @history
	 *
	 */
	public static void init() {
		try {
			String mappingFile = FileUtil.getRealPath(DataDictionaryConstants.DATA_DICTIONARY_MAPPING);
			String configFile = FileUtil.getRealPath(DataDictionaryConstants.DATA_DICTIONARY_CONFIG);
			Mapping mapping = new Mapping();
			mapping.loadMapping(mappingFile);
			Unmarshaller unmar = new Unmarshaller(mapping);
			InputSource input = new InputSource(configFile);
			input.setEncoding(Constants.DEFAULT_ENCODING);
			dataTypeList = (DataTypeList) unmar.unmarshal(input);
		} catch (Exception e) {
			log.error(e);
		}
	}

	/**
	 * 
	 * @function 根据类型id获取数据分类
	 * @param typeId 类型id
	 *
	 * @return 数据分类
	 * @exception
	 *
	 * @author Dormin
	 * @history
	 *
	 */
	public static DataType getDataTypeById(int typeId) {
		if (dataTypeMap.isEmpty()){
			for(DataType dataType : getDataTypeList().getTypeList()){
				dataTypeMap.put(dataType.getId(), dataType);
			}
		}
		
		return dataTypeMap.get(typeId);
	}

	/**
	 * 
	 * @function 用数据填充分类信息用以渲染表单模板
	 * @param obj 实体对象
	 * @param dataType 数据分类信息
	 *
	 * @return
	 * @exception
	 *
	 * @author Dormin
	 * @history
	 *
	 */
	public static List<DataItem> setDataItemValue(Object obj,DataType dataType) {
		List<DataItem> itemList = new ArrayList<DataItem>();
		if(dataType==null || obj==null){
			return itemList;
		}
		for(DataItem item:dataType.getItems()){
			
			DataItem newItem = new DataItem();
			try {
				BeanUtilsEx.copyProperties(item, newItem);
			} catch (IllegalAccessException e1) {
				log.error("DataDictionaryHelper.setDataItemValue(): IllegalAccessException", e1);
			} catch (InvocationTargetException e1) {
				log.error("DataDictionaryHelper.setDataItemValue(): InvocationTargetException", e1);
			}
			String fieldName = newItem.getFieldName();
			if(fieldName!=null && fieldName.length()>0){
				try{
					Object value = ReflectUtil.getProperty(obj, fieldName);
					newItem.setValue(value == null? "": value.toString());
					itemList.add(newItem);
				} catch (Exception e) {
					log.error(e);
				}
			}
		}
		return itemList;
	}

	/**
	 * 
	 * @function 将请求中的参数值转换为指定的类型的对象
	 * @param value 参数值
	 * @param typeClass 指定的类型
	 *
	 * @return
	 * @exception
	 *
	 * @author Dormin
	 * @history
	 *
	 */
	public static Object parseValue(String value,Class typeClass) {
		Object obj = null;
		if(typeClass==int.class || typeClass==Integer.class){
			obj = Integer.parseInt(value);
		}
		else if(typeClass==long.class || typeClass==Long.class){
			obj = Long.decode(value);
		}
		else if(typeClass==double.class || typeClass==Double.class){
			obj = Double.valueOf(value);
		}
		else if(typeClass==byte.class || typeClass==Byte.class){
			obj = Byte.parseByte(value);
		}
		else if(typeClass==boolean.class || typeClass==Boolean.class){
			obj = Boolean.valueOf(value);
		}
		else if(typeClass == String.class){
			obj = value;
		}
		return obj;
	}

}
